home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 039a / mawk10.zip / ERROR.C < prev    next >
C/C++ Source or Header  |  1991-10-05  |  9KB  |  380 lines

  1.  
  2. /********************************************
  3. error.c
  4. copyright 1991, Michael D. Brennan
  5.  
  6. This is a source file for mawk, an implementation of
  7. the AWK programming language.
  8.  
  9. Mawk is distributed without warranty under the terms of
  10. the GNU General Public License, version 2, 1991.
  11. ********************************************/
  12.  
  13.  
  14. /* $Log:    error.c,v $
  15.  * Revision 3.3.1.1  91/09/14  17:23:00  brennan
  16.  * VERSION 1.0
  17.  * 
  18.  * Revision 3.3  91/08/13  06:51:05  brennan
  19.  * VERSION .9994
  20.  * 
  21.  * Revision 3.2  91/06/28  04:16:26  brennan
  22.  * VERSION 0.999
  23.  * 
  24.  * Revision 3.1  91/06/07  10:27:12  brennan
  25.  * VERSION 0.995
  26.  * 
  27.  * Revision 2.6  91/05/28  15:17:41  brennan
  28.  * removed STRING_BUFF back to temp_buff.string_buff
  29.  * 
  30.  * Revision 2.5  91/05/28  09:04:38  brennan
  31.  * removed main_buff
  32.  * 
  33.  * Revision 2.4  91/05/16  12:19:36  brennan
  34.  * cleanup of machine dependencies
  35.  * 
  36.  * Revision 2.3  91/04/29  07:16:54  brennan
  37.  * changes to grammar to make $x++ and $A[3]++ work right
  38.  * 
  39.  * Revision 2.2  91/04/09  12:38:52  brennan
  40.  * added static to funct decls to satisfy STARDENT compiler
  41.  * 
  42.  * Revision 2.1  91/04/08  08:22:52  brennan
  43.  * VERSION 0.97
  44.  * 
  45. */
  46.  
  47.  
  48. #include  "mawk.h"
  49. #include  "scan.h"
  50. #include  "bi_vars.h"
  51.  
  52. #ifndef  EOF
  53. #define  EOF  (-1)
  54. #endif
  55.  
  56. /* statics */
  57. static void  PROTO( check_FILENAME, (void) ) ;
  58. static void  PROTO( unexpected_char, (void) ) ;
  59. static void  PROTO( missing, (int, char *, int) ) ;
  60. static char *PROTO( type_to_str, (int) ) ;
  61.  
  62.  
  63. static struct token_str  {
  64. short token ;
  65. char *str ; }  token_str[] = {
  66. EOF , "end of file" ,
  67. NL , "end of line",
  68. SEMI_COLON , ";" ,
  69. LBRACE , "{" ,
  70. RBRACE , "}" ,
  71. SC_FAKE_SEMI_COLON, "}",
  72. LPAREN , "(" ,
  73. RPAREN , ")" ,
  74. LBOX , "[",
  75. RBOX , "]",
  76. QMARK , "?",
  77. COLON , ":",
  78. OR, "||",
  79. AND, "&&",
  80. P_OR, "||",
  81. P_AND, "&&",
  82. ASSIGN , "=" ,
  83. ADD_ASG, "+=",
  84. SUB_ASG, "-=",
  85. MUL_ASG, "*=",
  86. DIV_ASG, "/=",
  87. MOD_ASG, "%=",
  88. POW_ASG, "^=",
  89. EQ  , "==" ,
  90. NEQ , "!=",
  91. LT, "<" ,
  92. LTE, "<=" ,
  93. GT, ">",
  94. GTE, ">=" ,
  95. MATCH, "~",
  96. NOT_MATCH, "!~",
  97. PLUS , "+" ,
  98. MINUS, "-" ,
  99. MUL , "*" ,
  100. DIV, "/"  , 
  101. MOD, "%" ,
  102. POW, "^" ,
  103. NOT, "!" ,
  104. COMMA, "," ,
  105. INC_or_DEC, temp_buff.string_buff,
  106. CONSTANT , temp_buff.string_buff ,
  107. ID , temp_buff.string_buff ,
  108. FUNCT_ID , temp_buff.string_buff ,
  109. BUILTIN , temp_buff.string_buff ,
  110. IO_OUT, temp_buff.string_buff, 
  111. IO_IN, "<" ,
  112. PIPE, "|" ,
  113. DOLLAR, "$" ,
  114. FIELD, "$" ,
  115. 0, (char *) 0 } ;
  116.  
  117. /* if paren_cnt >0 and we see one of these, we are missing a ')' */
  118. static int missing_rparen[] =
  119. { EOF, NL, SEMI_COLON, SC_FAKE_SEMI_COLON, RBRACE, 0 } ;
  120.  
  121. /* ditto for '}' */
  122. static int missing_rbrace[] =
  123. { EOF, BEGIN, END , 0 } ;
  124.  
  125. static void missing( c, n , ln)
  126.   int c ;
  127.   char *n ;
  128.   int ln ;
  129. { errmsg(0, "line %u: missing %c near %s" , ln, c, n) ; }
  130.   
  131. void  yyerror(s)
  132.   char *s ; /* we won't use s as input 
  133.   (yacc and bison force this).
  134.   We will use s for storage to keep lint or the compiler
  135.   off our back */
  136. { struct token_str *p ;
  137.   int *ip ;
  138.  
  139.   s = (char *) 0 ;
  140.  
  141.   for ( p = token_str ; p->token ; p++ )
  142.       if ( current_token == p->token )
  143.       { s = p->str ; break ; }
  144.  
  145.   if ( ! s )  /* search the keywords */
  146.          s = find_kw_str(current_token) ;
  147.  
  148.   if ( s )
  149.   {
  150.     if ( paren_cnt )
  151.         for( ip = missing_rparen ; *ip ; ip++)
  152.           if ( *ip == current_token )
  153.           { missing(')', s, token_lineno) ;
  154.             paren_cnt = 0 ;
  155.             goto done ;
  156.           }
  157.  
  158.     if ( brace_cnt )
  159.         for( ip = missing_rbrace ; *ip ; ip++)
  160.           if ( *ip == current_token )
  161.           { missing('}', s, token_lineno) ;
  162.             brace_cnt = 0 ;
  163.             goto done ;
  164.           }
  165.  
  166.     compile_error("syntax error at or near %s", s) ;
  167.  
  168.   }
  169.   else  /* special cases */
  170.   switch ( current_token )
  171.   {
  172.     case UNEXPECTED :
  173.             unexpected_char() ; 
  174.             goto done ;
  175.  
  176.     case BAD_DECIMAL :
  177.             compile_error(
  178.               "syntax error in decimal constant %s",
  179.               temp_buff.string_buff ) ;
  180.             break ;
  181.  
  182.     case RE :
  183.             compile_error(
  184.             "syntax error at or near /%s/", 
  185.             temp_buff.string_buff ) ;
  186.             break ;
  187.  
  188.     default :
  189.             compile_error("syntax error") ;
  190.             break ;
  191.   }
  192.   return ;
  193.  
  194. done :
  195.   if ( ++compile_error_count == MAX_COMPILE_ERRORS ) mawk_exit(1) ;
  196. }
  197.  
  198. /* system provided errnos and messages */
  199. #ifndef MSDOS_MSC    /* don't need the declarations */
  200. #ifndef THINK_C        /* don't WANT the declarations */
  201. extern int sys_nerr ;
  202. extern char *sys_errlist[] ;
  203. #endif
  204. #endif
  205.  
  206. #if  HAVE_STDARG_H
  207. #include <stdarg.h>
  208.  
  209. /* generic error message with a hook into the system error 
  210.    messages if errnum > 0 */
  211.  
  212. void  errmsg(int errnum, char *format, ...)
  213. { va_list args ;
  214.  
  215.   fprintf(stderr, "%s: " , progname) ;
  216.   va_start(args, format) ;
  217.   (void) vfprintf(stderr, format, args) ;
  218.   va_end(args) ;
  219. #ifdef THINK_C
  220.   if ( errnum > 0 )
  221.     fprintf(stderr, " (%s)" , strerror(errnum) ) ;
  222. #else
  223.   if ( errnum > 0 && errnum < sys_nerr )
  224.     fprintf(stderr, " (%s)" , sys_errlist[errnum]) ;
  225. #endif
  226.   fprintf( stderr, "\n") ;
  227. }
  228.  
  229. void  compile_error(char *format, ...)
  230. { va_list args ;
  231.  
  232.   fprintf(stderr, "%s: line %u: " , progname, token_lineno) ;
  233.   va_start(args, format) ;
  234.   vfprintf(stderr, format, args) ;
  235.   va_end(args) ;
  236.   fprintf(stderr, "\n") ;
  237.   if ( ++compile_error_count == MAX_COMPILE_ERRORS ) mawk_exit(1) ;
  238. }
  239.  
  240. void  rt_error( char *format, ...)
  241. { va_list args ;
  242.  
  243.   fprintf(stderr, "%s: run time error: " , progname ) ;
  244.   va_start(args, format) ;
  245.   vfprintf(stderr, format, args) ;
  246.   va_end(args) ;
  247.   check_FILENAME() ;
  248.   fprintf(stderr, "\n\t(FILENAME=\"%s\" FNR=%g NR=%g)\n" ,
  249.      string(bi_vars+FILENAME)->str, bi_vars[FNR].dval,
  250.      bi_vars[NR].dval) ;
  251.   mawk_exit(1) ;
  252. }
  253.  
  254. #else
  255.  
  256. #include <varargs.h>
  257.  
  258. /*  void errmsg(errnum, format, ...) */
  259.  
  260. void  errmsg( va_alist)
  261.   va_dcl
  262. { va_list ap ;
  263.   int errnum ;
  264.   char *format ;
  265.  
  266.   fprintf(stderr, "%s: " , progname) ;
  267.   va_start(ap) ;
  268.   errnum = va_arg(ap, int) ;
  269.   format = va_arg(ap, char *) ;
  270.   (void) vfprintf(stderr, format, ap) ;
  271. #ifdef THINK_C
  272.   if ( errnum > 0 )
  273.     fprintf(stderr, " (%s)" , strerror(errnum) ) ;
  274. #else
  275.   if ( errnum > 0 && errnum < sys_nerr )
  276.     fprintf(stderr, " (%s)" , sys_errlist[errnum]) ;
  277. #endif
  278.   fprintf( stderr, "\n") ;
  279. }
  280.  
  281. void compile_error( va_alist )
  282.   va_dcl
  283. { va_list args ;
  284.   char *format ;
  285.  
  286.   fprintf(stderr, "%s: line %u: " , progname, token_lineno) ;
  287.   va_start(args) ;
  288.   format = va_arg(args, char *) ;
  289.   vfprintf(stderr, format, args) ;
  290.   va_end(args) ;
  291.   fprintf(stderr, "\n") ;
  292.   if ( ++compile_error_count == MAX_COMPILE_ERRORS ) mawk_exit(1) ;
  293. }
  294.  
  295. void  rt_error( va_alist )
  296.   va_dcl
  297. { va_list args ;
  298.   char *format ;
  299.  
  300.   fprintf(stderr, "%s: run time error: " , progname ) ;
  301.   va_start(args) ;
  302.   format = va_arg(args, char *) ;
  303.   vfprintf(stderr, format, args) ;
  304.   va_end(args) ;
  305.   check_FILENAME() ;
  306.   fprintf(stderr, "\n\tFILENAME=\"%s\" FNR=%g NR=%g\n" ,
  307.      string(bi_vars+FILENAME)->str, bi_vars[FNR].dval,
  308.      bi_vars[NR].dval) ;
  309.   mawk_exit(1) ;
  310. }
  311.  
  312. #endif
  313.  
  314. void bozo(s)
  315.   char *s ;
  316. { errmsg(0, "bozo: %s" , s) ; mawk_exit(1) ; }
  317.  
  318. void overflow(s, size)
  319.   char *s ; unsigned size ;
  320. { errmsg(0 , "program limit exceeded: %s size=%u", s, size) ;
  321.   mawk_exit(1) ; }
  322.  
  323. static void check_FILENAME()
  324. {
  325.   if ( bi_vars[FILENAME].type != C_STRING )
  326.           cast1_to_s(bi_vars + FILENAME) ;
  327.   if ( bi_vars[FNR].type != C_DOUBLE )
  328.           cast1_to_d(bi_vars + FNR ) ;
  329.   if ( bi_vars[NR].type != C_DOUBLE )
  330.           cast1_to_d(bi_vars + NR ) ;
  331. }
  332.  
  333. /* run time */
  334. void rt_overflow(s, size)
  335.   char *s ; unsigned size ;
  336. { check_FILENAME() ;
  337.   errmsg(0 , 
  338.   "program limit exceeded: %s size=%u\n\
  339. \t(FILENAME=\"%s\" FNR=%g NR=%g)", 
  340.    s, size, string(bi_vars+FILENAME)->str, 
  341.    bi_vars[FNR].dval,
  342.    bi_vars[NR].dval) ;
  343.    mawk_exit(1) ;
  344. }
  345.  
  346. static void unexpected_char()
  347. { int c = yylval.ival ;
  348.  
  349.   fprintf(stderr, "%s: %u: ", progname, token_lineno) ;
  350.   if ( c > ' ')
  351.       fprintf(stderr, "unexpected character '%c'\n" , c) ;
  352.   else
  353.       fprintf(stderr, "unexpected character 0x%02x\n" , c) ;
  354. }
  355.  
  356. static char *type_to_str( type )
  357.   int type ;
  358. { char *retval ;
  359.  
  360.   switch( type )
  361.   {
  362.     case  ST_VAR :  retval = "variable" ; break ;
  363.     case  ST_ARRAY :  retval = "array" ; break ;
  364.     case  ST_FUNCT :  retval = "function" ; break ;
  365.     case  ST_LOCAL_VAR : retval = "local variable" ; break ;
  366.     case  ST_LOCAL_ARRAY : retval = "local array" ; break ;
  367.     default : bozo("type_to_str") ;
  368.   }
  369.   return retval ;
  370. }
  371.  
  372. /* emit an error message about a type clash */
  373. void type_error(p)
  374.   SYMTAB *p ;
  375. { compile_error("illegal reference to %s %s", 
  376.     type_to_str(p->type) , p->name) ;
  377. }
  378.  
  379.  
  380.